package com.gotokeep.keep.video;

import android.content.Context;
import android.media.MediaMetadataRetriever;
import android.text.TextUtils;
import android.util.Log;

import com.gotokeep.keep.KApplication;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Locale;

/**
 * @author  xana/cuixianming
 * @version 1.0
 * @since   2018-01-22 11:01
 */

public class FFmpegUtils {

    public static boolean initialize(Context context) {
        try {
            KeepVideoUtil.nativeInit();
            return true;
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return false;
    }

    public static int runCommands(String args) {
        return KeepVideoUtil.FFmpegRun("", "ffmpeg " + args);
    }
    public static int getDuration(String path) {
        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
        try {
            retriever.setDataSource(path);
        } catch (Exception e) {
            return 0;
        }
        String time = null;
        try {
            time = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
        } catch (Exception ex) {
            // ignore
        }
        time = time == null ? "0" : time.isEmpty() ? "0" : time;
        return Integer.parseInt(time);
    }

    private static int getVideoDuration(String video) {
        return Math.round((float) getDuration(video) / 1000);
    }

    public static String mixAudio(String video, String music, String output) {
        // ffmpeg -ss 00:00:00 -t [duration] -i [videoPath] -i [audioPath] -map 0:v -map 1:a -vcodec copy -acodec aac -shortest [output]
        int duration = getVideoDuration(video);
        String cmd = String.format(Locale.CHINA, "-ss 00:00:00 -t %d -i \"%s\" -i \"%s\" -map 0:v -map 1:a -c:v copy -c:a aac -shortest \"%s\"", duration, video, music, output);
        int ret = runCommands(cmd);
        if (ret == 0) {
            return output;
        } else {
            return "";
        }
    }

    public static String mergeImage(String videoPath, String imagePath, int x, int y, String output) {
        // ffmpeg -i videoPath -i imagePath -filter_complex overlay=0:0 -vcodec libx264 -profile:v baseline -preset ultrafast -b:v 5000k -g 30 -f mp4 outPath
        StringBuilder sb = new StringBuilder("-i");
        sb.append(" \"" + videoPath + "\"");
        sb.append(" -i");
        sb.append(" \"" + imagePath + "\"");
        sb.append(" -filter_complex");
        sb.append(" overlay=" + x + ":" + y );
        sb.append(" -vcodec libx264 -profile:v baseline -preset ultrafast -b:v 5000k -g 30");
        sb.append(" -f mp4");
        sb.append(" \"" + output + "\"");

        int i = runCommands(sb.toString());
        if (i == 0) {
            return output;
        } else {
            return "";
        }
    }

    public static String cutVideo(String videoPath, String output, int start, int end) {
        // ffmpeg -i 1.mp4 -ss 00:00:00 -t 00:00:10 11_cut.mp4
        StringBuilder sb = new StringBuilder("-i");
        sb.append(" \"" + videoPath + "\"");
        sb.append(" -ss 00:00:" + (start > 9 ? start : "0" + start));
        sb.append(" -t 00:00:" + (end > 9 ? end : "0" + end));
        sb.append(" \"" + output + "\"");

        int i = runCommands(sb.toString());
        if (i == 0) {
            return output;
        } else {
            return "";
        }
    }

    public static String processVideo(String videoPath, String output, int width, int height, int startMs, int endMs) {
        // ffmpeg -i VID_20171107_104956.mp4 -ss 00:00:00 -to 00:00:10 -c:v libx264 -preset superfast -vf scale=720:-2 -profile:v baseline compressed.mp4
        StringBuilder sb = new StringBuilder("-i ");
        sb.append("\"" + videoPath + "\""); // For file paths with spaces, we should add quotes for it.
        if (startMs >= 0 && endMs > startMs) {
            sb.append(" -ss " + formatTimeString(startMs)).append(" -to " + formatTimeString(endMs));
        }
        sb.append(" -c:v libx264 -preset superfast");
        sb.append(scaleString(width, height));
        sb.append(" -profile:v baseline ");
        sb.append("\"" + output + "\"");

        int i = runCommands(sb.toString());
        if (i == 0) {
            return output;
        } else {
            return "";
        }
    }

    private static String scaleString(int width, int height) {
        String aspectRatio = null;
        if (width >= height && height > 720) {
            aspectRatio = (int) (width * 720f / height) + ":720";
        } else if (height > width && width > 720) {
            aspectRatio = "720:" + (int) (height * 720f / width);
        }
        return TextUtils.isEmpty(aspectRatio) ? "" : " -vf scale=" + aspectRatio;
    }

    private static String formatTimeString(int timeMs) {
        return "00:" + new SimpleDateFormat("mm:ss.SSS").format(timeMs);
    }

    public static String rotateVideo(String path, int rotation, String output) {
        // ffmpeg -i input.mp4 -c copy -metadata:s:v:0 rotate=90 output.mp4
        StringBuilder sb = new StringBuilder("-i ");
        sb.append(" \"" + path + "\"");
        sb.append(" -c copy -metadata:s:v:0 rotate=");
        sb.append(rotation);
        sb.append(" \"" + output + "\"");

        int i = runCommands(sb.toString());
        if (i == 0) {
            return output;
        } else {
            return "";
        }
    }
}
